package com.codeberry.yws2;

import java.io.*;
import java.util.*;

public class Request {
  private String path;
  private String method;
  private String version;

  private RequestArgs args;

  public Request(InputStream requestInput) throws IOException {
    args = new RequestArgs();

    BufferedReader in = new BufferedReader(new InputStreamReader(requestInput, "ISO-8859-1"));
    String requestLine = in.readLine();
    StringTokenizer tok = new StringTokenizer(requestLine, " ");

    method = tok.nextToken();
    path = tok.nextToken();
    version = tok.nextToken();
    parsePathParams();

    if (isPost()) {
      String postData = readContentAsString(in);
      args.putArgsFromString(postData);
    }
  }

  private boolean isPost() {
    return "post".equalsIgnoreCase(method);
  }

  private String readContentAsString(BufferedReader in) throws IOException {
    int contentLength = skipHeadersAndGetContentLength(in);
    char[] buf = new char[contentLength];
    readFully(in, buf);
    return new String(buf);
  }

  private int skipHeadersAndGetContentLength(BufferedReader reader) throws IOException {
    int contentLength = 0;
    String tmp;
    while ((tmp = reader.readLine()) != null &&
           !tmp.isEmpty()) {
      //...skipping all headers
      tmp = tmp.trim().toLowerCase();
      if (tmp.startsWith("content-length:")) {
        contentLength = Integer.parseInt(tmp.substring(15).trim());
      }
    }
    return contentLength;
  }

  private void readFully(BufferedReader in, char[] buf) throws IOException {
    int off = 0;
    while ((off += in.read(buf, off, buf.length - off)) < buf.length) {
    }
  }

  private void parsePathParams() {
    int start = path.indexOf('?');
    if (start >= 0) {
      String queryString = path.substring(start + 1);
      args.putArgsFromString(queryString);
      path = path.substring(0, start);
    }
  }

  public String getPath() {
    return path;
  }

  public String getMethod() {
    return method;
  }

  public String getVersion() {
    return version;
  }

  public RequestArgs getArgs() {
    return args;
  }
}
